<script setup lang="ts">
import { onMounted, onUnmounted, ref, watch } from 'vue'
import { init as initEChart, type ECharts, type EChartsOption, type SeriesOption } from 'echarts'
import { getEntity } from '../../base'

import {
  SpeedType,
  SpeedUnit,
  SpeedUnitSelect,
  SpeedTypeSelect,
  LengthUnit,
  LengthUnitSelect,
  fromMpsConvert,
  speedUnitName,
  fromMeterConverter,
  lengthUnitName
} from '@/widgets'
import type { AircraftType, IASItem } from '../types'
import { ISA } from '@/atmosphere'

const props = defineProps<{
  id: string
  stage: 'Climb' | 'Cruise' | 'Descent'
}>()

const spdType = ref<SpeedType>(SpeedType.CAS)
const spdUnit = ref<SpeedUnit>(SpeedUnit.KT)
const altUnit = ref<LengthUnit>(LengthUnit.FT)

let iasList: IASItem[] = []
function initData() {
  const acType = getEntity<AircraftType>('AircraftType', props.id)
  const stage = props.stage
  if (acType) {
    if (stage === 'Climb') {
      iasList = acType.climbIASList
    } else if (stage === 'Cruise') {
      iasList = acType.cruiseIASList
    } else {
      iasList = acType.descentIASList
    }
  }
}

const chartEl = ref<HTMLDivElement>()
let chart: ECharts | null = null

function updateChart() {
  if (!chart) {
    return
  }
  chart.clear()
  const series = toSeries(iasList)
  const opts: EChartsOption = {
    title: {
      left: 'right',
      text: `${props.id} ${spdType.value}/高度`,
      subtext: `大气模型:\nISA\n飞行阶段:\n${props.stage}`
    },
    dataZoom: [
      {
        type: 'inside',
        // xAxisIndex: 0,
        yAxisIndex: 0,
        filterMode: 'none'
        // zoomOnMouseWheel: 'alt'
      },
      {
        type: 'inside',
        xAxisIndex: 0,
        // yAxisIndex: 0,
        filterMode: 'none'
        // zoomOnMouseWheel: 'ctrl'
      }
    ],
    tooltip: {
      trigger: 'item',
      formatter: '{a} <br /> {c}',
      axisPointer: { type: 'cross' }
    },
    legend: {},
    series,
    xAxis: {
      name: makeXName(),
      type: 'value'
    },
    yAxis: {
      name: makeYName(),
      type: 'value'
    }
  }
  chart.setOption(opts)
}

function makeYName(): string {
  if (spdType.value === SpeedType.Mach) {
    return '马赫'
  }
  if (spdType.value === SpeedType.CAS) {
    return 'CAS(' + speedUnitName(spdUnit.value) + ')'
  }
  return 'TAS(' + speedUnitName(spdUnit.value) + ')'
}

function makeXName(): string {
  return `高度(${lengthUnitName(altUnit.value)})`
}

interface SpeedItem {
  alt: number
  min: number
  norm: number
  max: number
  fuel: number
}

function toSpeedItemList(lst: IASItem[]): SpeedItem[] {
  const altFn1 = fromMeterConverter(altUnit.value)
  const altFn = (e: number) => Math.floor(altFn1(e))
  if (spdType.value === SpeedType.Mach) {
    return lst.map((e) => {
      const ad = ISA.getAirData(e.altitude)
      return {
        alt: altFn(e.altitude),
        min: e.min ? ad.CAS2Mach(e.min) : e.minMach,
        norm: e.norm ? ad.CAS2Mach(e.norm) : e.normMach,
        max: e.max ? ad.CAS2Mach(e.max) : e.maxMach,
        fuel: e.fuel
      }
    })
  }
  const fn1 = fromMpsConvert(spdUnit.value)
  const fn = (e: number) => Math.floor(fn1(e) * 100.0) / 100.0
  if (spdType.value === SpeedType.CAS) {
    return lst.map((e) => {
      const ad = ISA.getAirData(e.altitude)
      return {
        alt: altFn(e.altitude),
        min: fn(e.min || ad.mach2CAS(e.minMach)),
        norm: fn(e.norm || ad.mach2CAS(e.normMach)),
        max: fn(e.max || ad.mach2CAS(e.maxMach)),
        fuel: e.fuel
      }
    })
  }
  return lst.map((e) => {
    const ad = ISA.getAirData(e.altitude)
    return {
      alt: altFn(e.altitude),
      altM: e.altitude,
      altFt: e.altitude * 3.2808399,
      min: fn(e.min ? ad.CAS2TAS(e.min) : ad.mach2TAS(e.minMach)),
      norm: fn(e.norm ? ad.CAS2TAS(e.norm) : ad.mach2TAS(e.normMach)),
      max: fn(e.max ? ad.CAS2TAS(e.max) : ad.mach2TAS(e.maxMach)),
      fuel: e.fuel
    }
  })
}

function toSeries(iasLst: IASItem[]): SeriesOption[] {
  const lst = toSpeedItemList(iasLst)
  return [
    {
      type: 'line',
      name: 'min',
      data: lst.map((e) => [e.alt, e.min])
    },
    {
      type: 'line',
      name: 'norm',
      data: lst.map((e) => [e.alt, e.norm])
    },
    {
      type: 'line',
      name: 'max',
      data: lst.map((e) => [e.alt, e.max])
    }
  ]
}

onMounted(() => {
  initData()
  chart = initEChart(chartEl.value)
  updateChart()
})
onUnmounted(() => {
  chart?.dispose()
})

watch(spdType, updateChart)
watch(spdUnit, updateChart)
watch(altUnit, updateChart)
</script>
<template>
  <div class="act-ias-view">
    <div class="row">
      <div class="txt-box col-5em">速度类型</div>
      <SpeedTypeSelect v-model="spdType" style="margin-right: 3em" />
      <div class="txt-box col-5em">速度单位</div>
      <SpeedUnitSelect
        v-model="spdUnit"
        :options="[SpeedUnit.MPS, SpeedUnit.KMPH, SpeedUnit.KT]"
        style="margin-right: 3em"
      />
      <div class="txt-box col-5em">高度类型</div>
      <LengthUnitSelect v-model="altUnit" :options="[LengthUnit.M, LengthUnit.FT]" />
    </div>
    <div class="ias-chart" ref="chartEl"></div>
  </div>
</template>
<style lang="scss">
.act-ias-view {
  .ias-chart {
    margin-top: 2em;
    width: 50em;
    height: 40em;
  }
}
</style>
